module scene.selectplayer;

import std.math;

import scene.scene, mirdefine, mirshare, mirgame, mirsound;
import gui.gbutton, gui.msgbox;

import common.imagearray, common.lightfog;
import share.container, share.edcode, share.nettcp, share.protocol, share.types, share.dlist;

import allegro5.allegro;



const BACK_IMG_POS_X = 0;
const BACK_IMG_POS_Y = 0;

public class GameSelectPlayerScene : Scene
{
    private bool _is_active;
    private ImageArray _iarray;
    
    public this(Game game)
    {
        super(game, SceneType.SelectChr);

        _is_active = false;

        _iarray = new ImageArray;
        _iarray.FileName = "./Data/interface1c.wil";
        _iarray.LibType = LibraryType.UseCache;
        _iarray.IVersion = InternationalVersion.English;
    }
    
    public override void Initialize()
    {
        _iarray.initialize();

        MySocket.setHandler(&parsing);
    }
    
    public override void Finalize()
    {
        _iarray.finalize();
    }

    public override void MouseDown(uint button, in IntPoint pt)
    {
        if (button != 1) return;
        

    }
    
    public override void MouseUp(uint button, in IntPoint pt)
    {
        if (button != 1) return;
        

    }
    
    public override void MouseMove(in IntPoint pt)
    {

    }
    
    public override void OpenScene()
    {
        MySocket.ConnectToServer(g_szServerIP, g_nServerPort);
        _is_active = true;
    }
    
    public override void CloseScene()
    {
        _is_active = false;
    }
    
    public override void PlayScene()
    {
        const clear_color = al_map_rgba_f(0.0, 0.0, 0.0, 0.0);

        ALLEGRO_BITMAP* bmp;

        
        al_clear_to_color(clear_color);
        
        if (!_is_active) return;
        
        // draw background picture
        bmp = _iarray[IMG_IDX_SELECT_CHR_BACK];
        if (bmp !is null)
            al_draw_bitmap(bmp, BACK_IMG_POS_X, BACK_IMG_POS_Y, 0);
    }

    private bool parsing(int length, char[] datablock)
    {
        std.stdio.writeln("[SelectPlayer] Parsing length: ", length, " data: ", datablock);
        
        DefaultMessage msg;
        
        if (length < DEFBLOCKSIZE)
            return false;
        
        auto head = datablock[0 .. DEFBLOCKSIZE];
        auto bodyy = datablock[DEFBLOCKSIZE + 1 .. $];
        
        DecodeMessage(msg, head);
        
        switch (msg.Ident)
        {
            // Connection Lost(close Connection)
            case SM_OUTOFCONNECTION:
            {
                //m_Progress  = PRG_QUIT;                                 // Quit for Some Reason     ÇÁ·Î±×·¥ Á¾·á
                //Senmsgessage(g_xMainWnd.GetSafehWnd(), WM_DESTROY, NULL, NULL);
                break;
            }

            default: break;
        }
        
        return false;
    }
}






// Selection Define
const SELECT_NONE = -1;
const SELECT_FIRST = 0;
const SELECT_SECOND = 1;
const SELECT_THIRD = 2;

const _RENDER_STILL_1 = 0;
const _RENDER_AVI_IN = 1;
const _RENDER_STILL_2 = 2;
const _RENDER_AVI_OUT = 3;
const _RENDER_AVI_START = 4;
const _RENDER_STARTGAME = 5;

const ID_SEL_CHR_NEW_BTN = 0;
const ID_SEL_CHR_DEL_BTN = 1;
const ID_SEL_CHR_EXIT_BTN = 2;
const ID_SEL_CHR_START_BTN = 3;

// Charater Select Image Index
const IMG_IDX_SELECT_CHR_BACK = 50;
const IMG_IDX_SELECT_CREATE = 51;
const IMG_IDX_SELECT_DELETE = 52;
const IMG_IDX_SELECT_START = 53;
const IMG_IDX_SELECT_EXIT = 54;

// Empty Button Image Index
const IMG_IDX_EMPTY_BTN_UP = 23;
const IMG_IDX_EMPTY_BTN_ON = 24;
const IMG_IDX_EMPTY_BTN_DOWN = 25;

// Charater Create Image Index
const IMG_IDX_CREATE_CHR_BACK = 90;
const IMG_IDX_WAR_BTN_UP = 91;
const IMG_IDX_SOR_BTN_UP = 94;
const IMG_IDX_TAO_BTN_UP = 97;
const IMG_IDX_WAR_MALE_CREATE = 100;
const IMG_IDX_WAR_FEMALE_CREATE = 101;
const IMG_IDX_SOR_MALE_CREATE = 102;
const IMG_IDX_SOR_FEMALE_CREATE = 103;
const IMG_IDX_TAO_MALE_CREATE = 104;
const IMG_IDX_TAO_FEMALE_CREATE = 105;

const IDX_IMG_MALE_WAR = 150;
const IDX_IMG_MALE_WAR_FIRE = 180;
const IDX_IMG_FEMALE_WAR = 210;
const IDX_IMG_FEMALE_WAR_FIRE = 240;
const IDX_IMG_MALE_TAO = 270;
const IDX_IMG_MALE_TAO_FIRE = 300;
const IDX_IMG_FEMALE_TAO = 330;
const IDX_IMG_FEMALE_TAO_FIRE = 360;
const IDX_IMG_MALE_SOR = 390;
const IDX_IMG_MALE_SOR_FIRE = 420;
const IDX_IMG_FEMALE_SOR = 450;
const IDX_IMG_FEMALE_SOR_FIRE = 480;

// Button Positions
const CREATE_CHAR_BTN_POS_Y = 420;
const CREATE_CHAR_WAR_BTN_POS_X = 280;
const CREATE_CHAR_SOR_BTN_POS_X = 320;
const CREATE_CHAR_TAO_BTN_POS_X = 360;
const CREATE_CHAR_OK_BTN_POS_X = 500;
const CREATE_CHAR_OK_BTN_POS_Y = 460;
const CREATE_CHAR_OK_BTN_WIDTH = 72;
const CREATE_CHAR_OK_BTN_HEIGHT = 24;

// Position of Select buttons
const SELECT_CHAR_NEW_BTN_POS_X = 442;
const SELECT_CHAR_NEW_BTN_POS_Y = 98;
const SELECT_CHAR_ERASE_BTN_POS_X = 81;
const SELECT_CHAR_ERASE_BTN_POS_Y = 247;
const SELECT_CHAR_START_BTN_POS_X = 263;
const SELECT_CHAR_START_BTN_POS_Y = 53;
const SELECT_CHAR_EXIT_BTN_POS_X = 29;
const SELECT_CHAR_EXIT_BTN_POS_Y = 441;

const RETURN_SELECT_NONE = 0;
const RETURN_SELECT_NEW_BTN = 1;
const RETURN_SELECT_NEW_ERR = 2;
const RETURN_SELECT_DEL_BTN = 3;
const RETURN_SELECT_DEL_ERR = 4;
const RETURN_SELECT_START_BTN = 5;
const RETURN_SELECT_START_ERR = 6;


// Gender
const SEX_MAN = 0;
const SEX_WOMAN = 1;

// Job counts
const JOB_KIND = 3;       // Á÷¾÷ Á¾·ù


// Button IDs
const ID_CREATE_CHR_OK_BTN = 0;
const ID_CREATE_CHR_WAR_BTN = 1;
const ID_CREATE_CHR_SOR_BTN = 2;
const ID_CREATE_CHR_TAO_BTN = 3;

// Button Width & Height
const WIDTH_EMPTY_BTN = 100;
const HEIGHT_EMPTY_BTN = 26;
const WIDTH_JOB_BTN = 40;
const HEIGHT_JOB_BTN = 40;

const CHR_ANI_COUNT = 21;
const ANIMATION_TICK = 200;
const BLEND_TICK = 50;


struct ChrInfo
{
    public ubyte Class;
    public ubyte Gender;
    public ubyte Level;
    public string ChrName;
}

struct CreateInfo
{
    public ubyte Class;
    public ubyte Gender;
    public ubyte Level;
    public string ChrName;
    public string szID;
}

class CSelectChr
{
    public int m_nRenderState;
    public int m_nSelectChr;

    protected bool m_fIsActive;
    protected LightFog m_xLightFog;
    protected DList!ChrInfo m_pxSList;
    protected DList!IntRect m_pxrcList;
    protected ImageArray m_pxImage;
    protected GButton m_pBtn[4];
    protected IntPoint m_PosName;
    protected bool m_fIsButtonDown;
    protected int m_nChrCount;
    protected int m_nAnimationCount;
    protected int m_nBlend;
    protected int m_nRoll;


    public this()
    {
        m_nRenderState = 0;
        m_nAnimationCount = 0;
        m_nRoll = 0;
        m_nBlend = -999;
        m_fIsButtonDown = false;
    }

    public ~this()
    {
    }
    
    public void Create(ImageArray iarr, DList!ChrInfo pxList, DList!IntRect pxrcList, int nChrCount)
    {
        /*int nLoop;
        // Buttons
        BUTTONINFO CharProcBtnInfo[] ={
            { IMG_IDX_SELECT_CREATE,    SELECT_CHAR_NEW_BTN_POS_X,      SELECT_CHAR_NEW_BTN_POS_Y,      0,                  0}, // Create New Charector Button
            { IMG_IDX_SELECT_DELETE,    SELECT_CHAR_ERASE_BTN_POS_X,    SELECT_CHAR_ERASE_BTN_POS_Y,    0,                  0}, // Erase Charector Button
            { IMG_IDX_SELECT_EXIT,      SELECT_CHAR_EXIT_BTN_POS_X,     SELECT_CHAR_EXIT_BTN_POS_Y,     0,                  0}, // Exit Button
            { IMG_IDX_SELECT_START,     SELECT_CHAR_START_BTN_POS_X,    SELECT_CHAR_START_BTN_POS_Y,    0,                  0}, // Start Button                                 
        };
        
        m_pBtn = new CMirButton*[sizeof(CharProcBtnInfo)/sizeof(BUTTONINFO)];*/
        
        m_pxImage = iarr;
        m_pxSList = pxList;
        m_pxrcList = pxrcList;
        m_nChrCount = nChrCount;
        
        m_xLightFog.Init(al_map_rgb(125, 125, 125));
        
        for( int i = 0 ; i < 4; i++)
        {
            m_pBtn[i] = new GButton;
            //m_pBtn[i].addActionListener(this);
            guiMan.add(m_pBtn[i]);

            //m_pxImage->NewSetIndex(CharProcBtnInfo[nLoop].nID);
            //CharProcBtnInfo[nLoop].right = m_pxImage->m_lpstNewCurrWilImageInfo->shWidth;
            //CharProcBtnInfo[nLoop].bottom = m_pxImage->m_lpstNewCurrWilImageInfo->shHeight;
            //m_pBtn[nLoop]->SetBtn(&CharProcBtnInfo[nLoop]);
        }

        m_pBtn[0].createButton(iarr, IMG_IDX_SELECT_CREATE, IMG_IDX_SELECT_CREATE+1, SELECT_CHAR_NEW_BTN_POS_X, SELECT_CHAR_NEW_BTN_POS_Y);
        m_pBtn[0].setIsSimple(true);

        m_pBtn[1].createButton(iarr, IMG_IDX_SELECT_DELETE, IMG_IDX_SELECT_DELETE+1, SELECT_CHAR_ERASE_BTN_POS_X, SELECT_CHAR_ERASE_BTN_POS_Y);
        m_pBtn[1].setIsSimple(true);

        m_pBtn[2].createButton(iarr, IMG_IDX_SELECT_EXIT, IMG_IDX_SELECT_EXIT+1, SELECT_CHAR_EXIT_BTN_POS_X, SELECT_CHAR_EXIT_BTN_POS_Y);
        m_pBtn[2].setIsSimple(true);

        m_pBtn[3].createButton(iarr, IMG_IDX_SELECT_START, IMG_IDX_SELECT_START+1, SELECT_CHAR_START_BTN_POS_X, SELECT_CHAR_START_BTN_POS_Y);
        m_pBtn[3].setIsSimple(true);
    }
    
    //virtual HRESULT     OnButtonDown(WPARAM wParam, LPARAM lParam);
    //virtual HRESULT     OnButtonDown(POINT ptMouse);
    //virtual HRESULT     OnButtonUp(WPARAM wParam, LPARAM lParam);
    //virtual HRESULT     OnButtonUp(POINT ptMouse);
    //virtual HRESULT     OnKeyDown(WPARAM wParam, LPARAM lParam);
    //virtual LRESULT     OnMouseMove(WPARAM wParam, LPARAM lParam);

    public void OpenWnd()
    {
        m_fIsActive = true;
        m_nRenderState = 9;
        m_nBlend = 100;
    }

    public void CloseWnd()
    {
        m_fIsActive = false;
    }
    
    public void ShowChrInfo()
    {
        if (m_nChrCount > 0)
        {
            m_pxSList.MoveCurrentToTop();
            m_pxSList.MoveNode(m_nSelectChr);

            auto chrInfo = m_pxSList.getCurrentData();
            MyPen.drawText(m_PosName.getX(), m_PosName.getY(), AlWhite, chrInfo.ChrName);
        }
    }

    public void Update(int nLoopTime)
    {
        static int dwTicks = 0;

        if (!m_fIsActive) return;

        dwTicks +=nLoopTime;
        
        if (dwTicks > BLEND_TICK)
        {
            m_nBlend = m_nBlend +((m_nRenderState != 0)? dwTicks / BLEND_TICK *(m_nRenderState != 9 ? 1 : -1): 0);
            m_nRoll = (m_nRoll+ 2)%100;
            if (dwTicks > ANIMATION_TICK)
            {
                m_nAnimationCount++;
                m_nAnimationCount %= CHR_ANI_COUNT;
                dwTicks = 0;
            }
        }

        if ((m_nBlend>=100 && m_nRenderState!=9)||(m_nBlend<=0 && m_nRenderState==9))
        {
            m_nBlend = -1;
            m_nRenderState = m_nRenderState + 10;
        }
    }

    public void Render()
    {
        ImageInfo imgi;
        ALLEGRO_BITMAP* bmp;
        int i, nPx, nPy;

        IntPoint ptPos[] =
        [
            IntPoint(310, 310),  // One
            IntPoint(300, 270),  // Two-One
            IntPoint(360, 310),  // Two-Two
            IntPoint(250, 270),  // Three-One
            IntPoint(320, 310),  // Three-Two
            IntPoint(390, 340) 
        ]; // Three-Three*/


        if (m_fIsActive)
        {
            m_xLightFog.ClearSavedLightColor();

            // render buttons
            /*for (i = ID_SEL_CHR_NEW_BTN; i <= ID_SEL_CHR_START_BTN ; i++)   // ´ÜÃß ÀÓ½Ã
            {
                if(m_pBtn[i]->m_nState==BUTTON_STATE_DOWN)      // Draw Button when Button state is Downed..
                {
                    m_pxImage->NewSetIndex(m_pBtn[i]->m_nButtonID);
                    
                    g_xMainWnd.DrawWithImageForComp(m_pBtn[i]->m_Rect.left, m_pBtn[i]->m_Rect.top,
                                                    m_pxImage->m_lpstNewCurrWilImageInfo->shWidth,
                                                    m_pxImage->m_lpstNewCurrWilImageInfo->shHeight                  
                                                    , (WORD*)(m_pxImage->m_pbCurrImage));
                }
            }*/
            

            
            m_pxSList.MoveCurrentToTop();
            for (i = 0; i < m_nChrCount; i++)
            {
                auto chrInfo = m_pxSList.getCurrentData();

                // Draw Person
                auto index = (IDX_IMG_MALE_WAR  + chrInfo.Gender * 60 + chrInfo.Class * 120
                              + ((i == m_nSelectChr) ? m_nAnimationCount : 0));
                bmp = m_pxImage.GetCachedImageEx(index, imgi);
                if ( bmp !is null )
                {
                    nPx = ptPos[i + m_nChrCount - 1].getX() + imgi.PosX;
                    nPy = ptPos[i + m_nChrCount - 1].getY() + imgi.PosY;

                    al_draw_bitmap(bmp, nPx, nPy, 0);
                    //g_xMainWnd.DrawWithABlendCompDataWithBackBuffer(nPx,nPy
                    //                                                ,m_pxImage->m_lpstNewCurrWilImageInfo->shWidth,m_pxImage->m_lpstNewCurrWilImageInfo->shHeight
                    //                                                ,(WORD*)(m_pxImage->m_pbCurrImage),640,480,0xffff,0xffff,((m_nBlend>=0)? m_nBlend : 0));
                }

                // Draw Fire
                if (i == m_nSelectChr)
                {
                    index = IDX_IMG_MALE_WAR_FIRE + (chrInfo.Gender) * 60 + (chrInfo.Class) * 120
                        + (m_nAnimationCount);
                    bmp = m_pxImage.GetCachedImageEx(index, imgi);
                    if ( bmp !is null )
                    {
                        nPx = ptPos[i + m_nChrCount - 1].getX() + imgi.PosX;
                        nPy = ptPos[i + m_nChrCount - 1].getY() + imgi.PosY;

                        al_draw_bitmap(bmp, nPx, nPy, 0);
                        //g_xMainWnd.DrawWithABlendCompDataWithBackBuffer(nPx,nPy
                        //                                                ,m_pxImage->m_lpstNewCurrWilImageInfo->shWidth,m_pxImage->m_lpstNewCurrWilImageInfo->shHeight
                        //                                                ,(WORD*)(m_pxImage->m_pbCurrImage),640,480,0xffff,0x1f1f,((m_nBlend>=0)? m_nBlend : 50));
                        
                        auto nTemp = cast(int)(125.0f * sin(cast(double)(m_nRoll/10)));
                        
                        m_xLightFog.SetLightRadiusWithCircle(nPx+100,nPy+100,((m_nBlend>=0) ? 5 - ((m_nBlend)/20) : 5),125 + nTemp,255 + nTemp,255 + nTemp);
                    }
                }
                
                m_pxSList.MoveNextNode();
            }

            m_xLightFog.ShowLightFog();
            
            ShowChrInfo();
        }
    }


}
